﻿
package bdz.projects.lavender.opsm.ui {
	
	import bdz.projects.lavender.opsm.events.FlipBoxEvent;
	import bdz.projects.lavender.opsm.vo.ProductVO;
	import com.soulwire.display.PaperSprite;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import com.greensock.*;
	import com.greensock.easing.*;
	
	/**
	 * ...
	 * @author Donald
	 */
	public class FlipBox extends PaperSprite {
		
		public static const FLIP_HORIZONTAL:String = "horizontal";
		public static const FLIP_VERTICAL:String = "vertical";
		
		private var _flipSpeed:Number = .6;
		private var _flipEase:Function;
		private var _flipCounter:Number = 1;
		private var _flipOrientation:String = FLIP_HORIZONTAL;
		private var _flipData:ProductVO;
		private var _tweenStarted:Boolean = false;
		private var _displayQueue:Array;
		private var _currentTween:TweenMax;
		private var _tweening:Boolean = false;
		
		function FlipBox() {
			super();
			_displayQueue = new Array();
			pivot = new Point(.5, .5);
			_flipEase = Quart.easeOut;
			addEventListener(Event.ADDED_TO_STAGE, initializeComponent);
		}
		private function initializeComponent(evt:Event):void {
			stage.invalidate();
		}
		override protected function update(event:Event = null):void {
			super.update(event);
		}
		
		private function tweenStarting():void {	
			_flipCounter++;
			alignFaces();
		}
		private function tweenCompleted():void {
			alignFaces();
			_flipOrientation = FLIP_HORIZONTAL;
			if (_displayQueue.length) {	
				flipActiveFace();
			}else {
				_tweening = false;
				dispatchEvent(new FlipBoxEvent(FlipBoxEvent.TRANSITION_DONE));
			}
		}
		private function flipActiveFace(getlast:Boolean = false):void {
			if (_displayQueue.length) {
				var displayInfo:Object = getlast ? _displayQueue.pop() : _displayQueue.shift();
				if (getlast) {
					_displayQueue = [];
				}
				if (isFrontFacing) {
					back = displayInfo.display;
				}else {
					front = displayInfo.display;	
				}
				if (_flipOrientation == FLIP_VERTICAL) {
					
					TweenMax.to(this, (displayInfo.info && displayInfo.info.speed) ? displayInfo.info.speed : _flipSpeed, { rotationX:_flipCounter * 180, ease:(displayInfo.info && displayInfo.info.ease) ? displayInfo.info.ease : _flipEase, onStart:tweenStarting, onComplete:tweenCompleted } );
				}else {
					
					TweenMax.to(this, (displayInfo.info && displayInfo.info.speed) ? displayInfo.info.speed : _flipSpeed, { rotationY:_flipCounter * 180, ease:(displayInfo.info && displayInfo.info.ease) ? displayInfo.info.ease : _flipEase, onStart:tweenStarting, onComplete:tweenCompleted } );
				}
			}
		}
		public function activateFace(d:DisplayObject, delay:Number = 0, info:Object = null):void {
			_displayQueue.push( { display:d, delay:delay, info:info } );
			if (!_tweening) {
				_tweening = true;
				TweenMax.delayedCall(delay, flipActiveFace);
			}	
		}
		public function set flipEase(f:Function):void {
			_flipEase = f;
		}
		public function get flipEase():Function {
			return _flipEase;
		}
		public function set flipSpeed(n:Number):void {
			_flipSpeed = n;
		}
		public function get flipSpeed():Number {
			return _flipSpeed;
		}
		public function set flipData(fd:ProductVO):void {
			_flipData = fd;
		}
		public function get flipData():ProductVO {
			return _flipData;
		}
		public function set flipOrientation(str:String):void {
			_flipOrientation = str;
		}
		public function get flipOrientation():String {
			return _flipOrientation;
		}
		public function clear():void {
			removeChild(_front);
			removeChild(_back);
		}
		
		override public function set back( value:DisplayObject ):void {
			if ( _back && contains( _back ) )
			{
				removeChild( _back );
			}
			try{
				_back = addChild( value );
				if(_flipOrientation == FLIP_HORIZONTAL){
					_back.scaleX = -1;
				}else {
					_back.scaleY = -1;
				}
				
			}catch (e:Error) { }
			alignFaces();
		}
		override public function set front( value:DisplayObject ):void {
			if ( _front && contains( _front ) )
			{
				removeChild( _front );
			}
			try{
				_front = addChild( value );
			}catch (e:Error) { }
			alignFaces();
		}
		
	}
	
}